package com.zhongyouyun.other.aspect;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhongyouyun.admin.model.DeptModel;
import com.zhongyouyun.admin.model.RoleModel;
import com.zhongyouyun.admin.model.UserModel;
import com.zhongyouyun.admin.service.DeptService;
import com.zhongyouyun.admin.service.RoleService;
import com.zhongyouyun.admin.service.UserService;
import com.zhongyouyun.config.RedisConfig;
import com.zhongyouyun.other.annotation.DataAuthScope;
import com.zhongyouyun.utils.LongUtil;
import com.zhongyouyun.utils.StringUtils;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 数据过滤处理
 *
 * @author wangfenglei
 */
@Aspect
@Component
public class DataAuthScopeAspect {
    public static final ThreadLocal DATA_AUTH_THREAD_LOCAL = new ThreadLocal();
    /**
     * 全部数据权限
     */
    public static final Integer DATA_SCOPE_ALL = 1;

    /**
     * 部门数据权限
     */
    public static final Integer DATA_SCOPE_DEPT = 2;

    /**
     * 部门及以下数据权限
     */
    public static final Integer DATA_SCOPE_DEPT_AND_CHILD = 3;

    /**
     * 仅本人数据权限
     */
    public static final Integer DATA_SCOPE_SELF = 4;

    @Resource
    private RedisConfig redisConfig;

    @Resource
    private DeptService deptService;
    @Resource
    private RoleService roleService;
    @Resource
    private UserService userService;

    @Before("@annotation(controllerDataAuthScope)")
    public void doBefore(JoinPoint point, DataAuthScope controllerDataAuthScope) throws Throwable {
        DATA_AUTH_THREAD_LOCAL.remove();
        handleDataAuthScope(point, controllerDataAuthScope);
    }

    @After("@annotation(controllerDataAuthScope)")
    public void doAfter(DataAuthScope controllerDataAuthScope) throws Throwable {
        //清空数据权限拼接SQL
        DATA_AUTH_THREAD_LOCAL.remove();
    }

    /**
     * 处理数据权限
     *
     * @param joinPoint     切面
     * @param dataAuthScope 数据权限
     */
    protected void handleDataAuthScope(final JoinPoint joinPoint, DataAuthScope dataAuthScope) {
        // 获取当前的用户
        Subject subject = SecurityUtils.getSubject();
        if (ObjectUtil.isNotEmpty(subject)) {
            Object object = redisConfig.get(subject.getSession().getId().toString());
            if (ObjectUtil.isNotEmpty(object)) {
                Object u = SecurityUtils.getSubject().getPrincipal();
                if (u instanceof UserModel) {
                    UserModel userModel = (UserModel) u;

                    if (ObjectUtil.isEmpty(userModel.getRoleId())) {
                        return;//超級管理員不管
                    }
                    userModel=userService.getById(userModel.getId());
                    if (ObjectUtil.isNotEmpty(userModel.getRoleId())) {
                        //添加角色数据
                        QueryWrapper roleModelQueryWrapper = new QueryWrapper<RoleModel>();
                        roleModelQueryWrapper.in("id", LongUtil.Longva(userModel.getRoleId().split(",")));
                        List<RoleModel> roleModelList = roleService.selectList(roleModelQueryWrapper);
                        userModel.setRoleModelList(roleModelList);
                    }
                    List<RoleModel> roleModelList = userModel.getRoleModelList();
                    //集团管理员
                    if (ObjectUtil.isNotEmpty(userModel.getDeptId())) {
                        //添加部门数据
                        QueryWrapper deptModelQueryWrapper = new QueryWrapper<DeptModel>();
                        deptModelQueryWrapper.eq("id", userModel.getDeptId());
                        List<DeptModel> deptModelList = deptService.selectList(deptModelQueryWrapper);
                        deptModelList.forEach(deptModel -> {
                            String chihids = deptService.getchild(deptModel.getId());
                            deptModel.setFullPathId(chihids);
                        });
                        userModel.setDeptModelList(deptModelList);
                    }
                    List<DeptModel> deptModelList = userModel.getDeptModelList();
                    for (RoleModel roleModel : roleModelList) {
                        if ("0".equals(roleModel.getType())) {
                            return;
                        }
                    }
                    List<Long> departIdList = new ArrayList<>();
                    List<Long> userIdList = new ArrayList<>();
                    for (DeptModel deptModel : deptModelList) {
                        if (DATA_SCOPE_ALL.equals(deptModel.getDataScope())) {
                            continue;
                        } else if (DATA_SCOPE_DEPT.equals(deptModel.getDataScope())) {
                            departIdList.add(deptModel.getId());
                        } else if (DATA_SCOPE_DEPT_AND_CHILD.equals(deptModel.getDataScope())) {
                            List<Long> departIds = getChildDepartIdList(deptModel);
                            if (!CollectionUtils.isEmpty(departIds)) {
                                departIdList.addAll(departIds);
                            }
                        } else if (DATA_SCOPE_SELF.equals(deptModel.getDataScope())) {
                            userIdList.add(userModel.getId());
                        }
                    }
                    StringBuilder sqlString = new StringBuilder();
                    //如果需要部门权限
                    if (!CollectionUtils.isEmpty(departIdList)) {
                        sqlString.append(StringUtils.sqlformat(" OR {}dept_id IN ({})", dataAuthScope.deptAlias(), LongUtil.getDepartSqlStr(departIdList)));
                    } else if (!CollectionUtils.isEmpty(userIdList)) {
                        sqlString.append(StringUtils.sqlformat(" OR {}createBy = {}", dataAuthScope.userAlias(), userModel.getId().toString()));
                    }

                    if (StrUtil.isNotBlank(sqlString.toString())) {
                        //设置数据权限拼接sql
                        DATA_AUTH_THREAD_LOCAL.set(" AND (" + sqlString.substring(4) + ")");
                    }
                } else {
                    return;
                }
            } else {
                return;
            }
        } else {
            return;
        }
    }
    /**
     * 获取本部门和子部门ID列表
     *
     * @param deptModel 部门信息
     * @return 本部门和子部门ID列表
     */
    private static List<Long> getChildDepartIdList(DeptModel deptModel) {
        String PIdStr = deptModel.getFullPathId();
        PIdStr = PIdStr.replace("$,", "").replace(",0", "");
        String[] childArr = PIdStr.split(",");
        return LongUtil.Longva(childArr);
    }


}